Ext.namespace('Myfuse');
Myfuse.Constants = {};
Myfuse.Constants.EXT_PAGING_TOTAL_COUNT = 'total';
Myfuse.Constants.EXT_PAGING_CONTENT = 'content';

Myfuse.Constants.Record = {};
Myfuse.Constants.Record.STATE_NONE = 0;
Myfuse.Constants.Record.STATE_ADD = 1;
Myfuse.Constants.Record.STATE_UPDATE = 2;
Myfuse.Constants.Record.STATE_REMOVE = 3;

Myfuse.Utils = {};

/**
 * 把form的fields和grid绑定；fields改动，对应的record跟着改动；record改动，fields跟着改动。
 * 
 * <pre>
 * Myfuse.Utils.bindGridAndForm(grid, form, [{
    	gridFieldId: 'userId',
    	formFieldName: 'userId'
    }, {
    	gridFieldId: 'name',
    	formFieldName: 'name'
    }, {
    	gridFieldId: 'email',
    	formFieldName: 'email'
    }]);
    </pre>
    
 * @param {} grid
 * @param {} form
 * @param {} mapList
 */
Myfuse.Utils.bindGridAndForm = function(grid, form, mapList) {
	var config = mapList;
	grid.on('rowclick', function(grid, rowIndex, e) {
		var record = grid.getStore().getAt(rowIndex);
		Ext.each(config, function(){
			form.find('name', this.formFieldName)[0].setValue(record.get(this.gridFieldId));
		})
	});
	
	var store = grid.getStore();
	var record = grid.getSelectionModel().getSelected();
	Ext.each(config, function(){
		var field = form.find('name', this.formFieldName)[0];
		field.on('change', function(field, newValue, oldValue){
			if (oldValue != newValue) {
				var record = grid.getSelectionModel().getSelected();
				record.set(field.getName(), newValue);
			}
		});
	});
	store.on('update', function(store, record, operation){
		Ext.each(config, function(){
			var field = form.find('name', this.formFieldName)[0];
			field.setValue(record.get(this.gridFieldId));
		})
	});
	
}

///////////
Myfuse.Utils.failHandler = function(response, options){
//    console.warn('error: ' + response.statusText);
    var win = new Ext.Window({
        title: 'error',
        html: response.responseText,
        buttons: [{
            text: 'Ok',
            handler: function(){
                win.setVisible(false);
            }
        }]
    });
    win.setVisible(true);
}

Myfuse.Utils.find = function(array, prop, value) {
	for(var i=0; i<array.length; i++) {
		for(var o in array[i]) {
			if (array[i][prop] == value) {
				return array[i];
			}
		}
	}
	return null;
}
////////////// all-in-one-grid
//Ext.data.Store.prototype.customerBuffer = {};

///////// Myfuse.Command
Myfuse.Command = function(config) {
	Ext.apply(this, config);
}
Myfuse.Command.prototype = {
	parameters: {},
	datasets: [],
	action: '',
	method: '',
	execute: function() {
		var data = {
			parameters: this.parameters,
			datasets: this.datasets
		}
		if (this.action == '' || this.method == '') {
			Ext.Msg.alert('error', 'action or method is null, request abort!');
			return ;
		}
		var command = this;
		Ext.Ajax.request({
			url: Myfuse.ContextPath + '/DataEngineServlet',
			params: {action: this.action, method: this.method},
			jsonData: data,
			success: function(response){
		        var r = Ext.util.JSON.decode(response.responseText);
		        if (!r.result) {
		            Ext.Msg.alert('error', r.errorMsg);
		        } else {
		            command.onSuccess(r);
		        }
		    },
		    failure: function(response){
		        //var r = Ext.util.JSON.decode(response.responseText);
		        Ext.Msg.alert('error', response.responseText);
		    }
		});
	},
	onSuccess: function(response) {
		
	}
}

////// Myfuse.Reader
Myfuse.JsonReader = function(meta, recordType){
    meta = meta || {};
    this.datasetId = meta.datasetId;
    Myfuse.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
};
Ext.extend(Myfuse.JsonReader, Ext.data.JsonReader, {
	read : function(response){
		var json = response.responseText;
        var o = eval("("+json+")");
        if(!o) {
            throw {message: "JsonReader.read: Json object not found"};
        }
        if(o.metaData){
            delete this.ef;
            this.meta = o.metaData;
            this.recordType = Ext.data.Record.create(o.metaData.fields);
            this.onMetaChange(this.meta, this.recordType, o);
        }
        if (console) console.info(this.datasetId);
        var dataset = Myfuse.Utils.find(o.datasets, 'datasetId', this.datasetId);
    	o = dataset;
    	if (console) console.info(o);
        return this.readRecords(o);
	}
});


////// Myfuse.Store
Myfuse.Store = function(config){
    Ext.apply(this, config);
    Myfuse.Store.superclass.constructor.call(this);
    this.on('add', function(store, records, index) {
		if (console) console.info('add, ' + index);
		store.customBuffer.add = store.customBuffer.add.concat(records);
		Ext.each(records, function() {
			console.info(this);
//        			this.custom.state = 'add';
		});
//        			record.custom = {};
//        			record.custom.state = 'add';
			
	});
	this.on('update', function(store, record, operation) {
		if (console) console.info(operation + ', ' + record);
//        		form.find('name', 'name')[0].setValue(record.get('name'));
		
		if (operation == Ext.data.Record.EDIT) {
			if (store.customBuffer.add.indexOf(record) == -1 && store.customBuffer.update.indexOf(record) == -1) {
				store.customBuffer.update.push(record);
			}
		}
		if (operation == Ext.data.Record.REJECT) {
			store.customBuffer.update.remove(record);
		}
		if (operation == Ext.data.Record.COMMIT) {
			/// commit data
			console.info(record);
			store.customBuffer.update.remove(record);
		}
	});
	this.on('remove', function(store, record, index) {
		if (console) console.info('remove, ' + index);
		if (store.customBuffer.add.indexOf(record) != -1) {
			store.customBuffer.add.remove(record);
			return;
		}
		if (store.customBuffer.update.indexOf(record) != -1) {
			store.customBuffer.update.remove(record);
		}
		store.customBuffer.remove.push(record);
	});
			
};
Ext.extend(Myfuse.Store, Ext.data.Store, {
    customBuffer: {'add': [], 'update': [], 'remove': []},
    showCaches: function() {
    	Ext.Msg.alert('caches', this.customBuffer);
    }
});